/*
 * $Id$
 *
 * Copyright ( c ) 2014 XuNuo Corporation. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of XuNuo
 * Corporation ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with the terms
 * of the license agreement you entered into with XuNuo Corporation or a XuNuo
 * authorized reseller (the "License Agreement"). XuNuo may make changes to the
 * Confidential Information from time to time. Such Confidential Information may
 * contain errors.
 *
 * EXCEPT AS EXPLICITLY SET FORTH IN THE LICENSE AGREEMENT, XuNuo DISCLAIMS ALL
 * WARRANTIES, COVENANTS, REPRESENTATIONS, INDEMNITIES, AND GUARANTEES WITH
 * RESPECT TO SOFTWARE AND DOCUMENTATION, WHETHER EXPRESS OR IMPLIED, WRITTEN OR
 * ORAL, STATUTORY OR OTHERWISE INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A
 * PARTICULAR PURPOSE. XuNuo DOES NOT WARRANT THAT END USER'S USE OF THE
 * SOFTWARE WILL BE UNINTERRUPTED, ERROR FREE OR SECURE.
 *
 * XuNuo SHALL NOT BE LIABLE TO END USER, OR ANY OTHER PERSON, CORPORATION OR
 * ENTITY FOR INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL
 * DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE, DATA OR USE, WHETHER IN AN
 * ACTION IN CONTRACT, TORT OR OTHERWISE, EVEN IF XuNuo HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES. XuNuo' TOTAL LIABILITY TO END USER SHALL NOT
 * EXCEED THE AMOUNTS PAID FOR THE XuNuo SOFTWARE BY END USER DURING THE PRIOR
 * TWELVE (12) MONTHS FROM THE DATE IN WHICH THE CLAIM AROSE.  BECAUSE SOME
 * STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL
 * OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO END USER.
 *
 * Copyright version 2.0
 */
package com.th.supcom.pds.drugreturn.client.widget;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.th.supcom.framework.web.gwt.client.widget.FcMessageBox;
import com.th.supcom.pds.common.client.commom.PdsAuditPrescServiceFactory;
import com.th.supcom.pds.common.client.commom.PdsAuditPrescServiceFactory2;
import com.th.supcom.pds.common.client.model.CodeConstants;
import com.th.supcom.pds.common.client.model.PdsSupplyModel;
import com.th.supcom.pds.common.enums.BatchNumberManagerFlag;
import com.th.supcom.pds.common.utils.ClientUtils;
import com.th.supcom.pds.dispensedrug.client.service.PdsSupplyDetailRpcAsync;
import com.th.supcom.pds.dispensedrug.client.service.PdsSupplyRpcAsync;
import com.th.supcom.pds.drugreturn.client.service.DrugReturnRpcAsync;
import com.th.supcom.pds.internal.client.model.PatientInfoModel;
import com.th.supcom.pds.internal.client.model.PrescAndPatResultModel;
import com.th.supcom.pds.prescstatusquery.client.widget.SupplyStatusQueryWindow;
import com.th.supcom.pds.sortingdrug.client.model.PdsPrescDetailInfoModel;

/**
 * 门诊退药Action
 * 
 * @author yzhang
 */
public class DrugReturnAction
{
    private static final PdsSupplyDetailRpcAsync PD_ASYNC = PdsAuditPrescServiceFactory.getPdsPrescDetailService ();
    private static final DrugReturnRpcAsync S_DRUG_RETURN_ASYNC = PdsAuditPrescServiceFactory2.getDrugReturnService ();
    private static final PdsSupplyRpcAsync S_PRESC_RPC_ASYNC = PdsAuditPrescServiceFactory.getPdsPrescService ();
    /** 提交路径. */
    public static final String SCC_BRANCH = "$URL$";
    /** 提交日期. */
    public static final String SCC_LAST_MODIFICATION_DATE = "$Date$";

    /** 最终修改人员. */
    public static final String SCC_LAST_MODIFIER_NAME = "$Author$";
    /** 最终版本号. */
    public static final String SCC_REVISION = "$Revision$";

    private DrugReturnAndRefundFields m_drugReturnAndRefundFields;

    private DrugReturnAndRefundPrescPanel m_drugReturnAndRefundPrescPanel;

    private DrugReturnPrescDetailPanel m_drugReturnPrescDetailPanel;

    private DrugReturnRefuseWindow m_drugReturnRefuseWindow;

    private List <List <PdsPrescDetailInfoModel>> m_memoryList;
    private DrugReturnMainPanel m_drugReturnMainPanel;

    /**
     * 构造函数
     */
    public DrugReturnAction ()
    {

    }

    /**
     * 清除
     */
    public void clear (final boolean isClearAll)
    {
        if (isClearAll)
        {
            m_drugReturnAndRefundFields.getMedicareCardField ().clear ();
            m_drugReturnAndRefundFields.getPrescNoField ().clear ();
            m_drugReturnAndRefundFields.getMedicareCardField ().focus ();
        }
        m_memoryList = null;
        m_drugReturnPrescDetailPanel.getPrescDetailGrid ().clear ();
        m_drugReturnAndRefundPrescPanel.refresh (null);
        m_drugReturnAndRefundFields.getPrescSource ().clear ();
        m_drugReturnAndRefundFields.getPatiNameField ().clear ();
        m_drugReturnAndRefundFields.getPatiIdField ().clear ();
        m_drugReturnAndRefundFields.getBirthDaTetField ().clear ();
        m_drugReturnAndRefundFields.getRemainingSumField ().clear ();
        m_drugReturnAndRefundFields.getSexField ().clear ();

        m_drugReturnAndRefundFields.getVisitTypeNameField ().clear ();
        m_drugReturnAndRefundFields.getVisitIdField ().clear ();
        m_drugReturnAndRefundFields.getVisitBeginDateField ().clear ();
        m_drugReturnAndRefundFields.getDeptNameField ().clear ();
        m_drugReturnAndRefundFields.getDay ().clear ();
        m_drugReturnAndRefundFields.getNumber ().clear ();

    }

    /**
     * 退药操作动作
     * 
     * @param successComponent
     * @param failComponent
     * @param be
     */
    private void doWithdramDrugAction (final Component successComponent, final Component failComponent,
                                       final MessageBoxEvent be)
    {
        final Button btn = be.getButtonClicked ();
        if (btn.getText ().equals ("否"))
        {
            failComponent.focus ();
            return;
        }

        // 获取勾选处方主记录
        final List <PdsPrescDetailInfoModel> prescLists = m_drugReturnAndRefundPrescPanel.getCheckmodel ()
                                                                                         .getSelectedItems ();

        final List <PdsPrescDetailInfoModel> prescDetailList = m_drugReturnPrescDetailPanel.getPrescDetailGrid ()
                                                                                           .getDetailData ();

        final String operator = ClientUtils.geteEmpModel ().getEmpCode ();
        DrugReturnAction.S_DRUG_RETURN_ASYNC.drugReturnPass (prescLists, prescDetailList, operator,
                                                             new AsyncCallback <Void> ()
                                                             {
                                                                 @Override
                                                                 public void onFailure (final Throwable caught)
                                                                 {
                                                                     ClientUtils.alertMessageBox (caught.getLocalizedMessage (),
                                                                                                  successComponent);
                                                                     clear (false);
                                                                 }

                                                                 @Override
                                                                 public void onSuccess (final Void result)
                                                                 {
                                                                     Info.display (CodeConstants.PROMPT, "退药成功");
                                                                     clear (true);
                                                                     if (null != successComponent)
                                                                     {
                                                                         successComponent.focus ();
                                                                     }

                                                                 }
                                                             });
    }

    /**
     * 当点击主处方表格处方时 处方明细表格相应弹出或隐藏内容
     * 
     * @param selectedModel
     */
    public void doSelectedChange (List <PdsPrescDetailInfoModel> selectedModel)
    {
        if (selectedModel == null || selectedModel.isEmpty ())
        {
            m_drugReturnPrescDetailPanel.getPrescDetailGrid ().getGrid ().getStore ().removeAll ();
        }
        if (m_memoryList == null || m_memoryList.isEmpty ())
        {
            return;
        }
        final List <PdsPrescDetailInfoModel> prescDetails = ClientUtils.getPrescDetailSelected (selectedModel,
                                                                                                m_memoryList.get (1));
        m_drugReturnPrescDetailPanel.getPrescDetailGrid ().getGrid ().getStore ().removeAll ();
        m_drugReturnPrescDetailPanel.getPrescDetailGrid ().getGrid ().getStore ().add (prescDetails);
    }

    /**
     * 门诊退药确认
     * 
     * @param successComponent
     * @param failComponent
     */
    public void drugReturn (final Component successComponent, final Component failComponent)
    {
        List <PdsPrescDetailInfoModel> detailModels = m_drugReturnPrescDetailPanel.getPrescDetailGrid ().getGrid ()
                                                                                  .getStore ().getModels ();
        final List <PdsPrescDetailInfoModel> prescModels = m_drugReturnAndRefundPrescPanel.getCheckmodel ()
                                                                                          .getSelectedItems ();
        if (m_drugReturnAndRefundPrescPanel.getCheckmodel ().getSelectedItems ().isEmpty ())
        {
            ClientUtils.alertMessageBox ("请先选中相应的处方信息再进行此操作。", failComponent);
            return;
        }
        detailModels = ClientUtils.getPrescDetailSelected (prescModels, detailModels);
        for (final PdsPrescDetailInfoModel model : detailModels)
        {
            if ((model.getPhamBatchNumber () == null || model.getReceiptDate () == null)
                && BatchNumberManagerFlag.OnBatchManager.getEnumCode ().equals (model.getBatchNumberManagerFlag ()))
            {
                ClientUtils.alertMessageBox ("请先输入批次号和有效期再进行此操作。", failComponent);
                return;
            }
        }
        FcMessageBox.confirm ("提示", "确定进行退药操作?", new Listener <MessageBoxEvent> ()
        {
            @Override
            public void handleEvent (final MessageBoxEvent be)
            {
                doWithdramDrugAction (successComponent, failComponent, be);
            }

        }, Dialog.YES);
    }

    /**
     * 门诊退药拒绝
     * 
     * @param successComponent
     * @param failComponent
     */
    public void drugReturnRefuse (final Component successComponent, final Component failComponent)
    {
        if (m_drugReturnAndRefundPrescPanel.getCheckmodel ().getSelectedItems ().isEmpty ())
        {
            ClientUtils.alertMessageBox ("请先选中相应的处方信息再进行此操作。", failComponent);
            return;
        }
        // 获取勾选处方主记录
        final List <PdsPrescDetailInfoModel> prescLists = m_drugReturnAndRefundPrescPanel.getCheckmodel ()
                                                                                         .getSelectedItems ();

        final List <PdsPrescDetailInfoModel> prescDetailList = m_drugReturnPrescDetailPanel.getPrescDetailGrid ()
                                                                                           .getDetailData ();
        final String operator = ClientUtils.geteEmpModel ().getEmpCode ();
        DrugReturnAction.S_DRUG_RETURN_ASYNC.drugReturnRefuse (prescLists, prescDetailList, operator,
                                                               new AsyncCallback <Void> ()
                                                               {

                                                                   @Override
                                                                   public void onFailure (final Throwable caught)
                                                                   {
                                                                       ClientUtils.alertMessageBox (caught.getLocalizedMessage (),
                                                                                                    failComponent);

                                                                   }

                                                                   @Override
                                                                   public void onSuccess (final Void result)
                                                                   {
                                                                       Info.display (CodeConstants.PROMPT, "该处方退药被拒绝");
                                                                       m_drugReturnRefuseWindow.hide ();
                                                                       successComponent.focus ();
                                                                       clear (true);
                                                                   }
                                                               });
    }

    /**
     * 查询患者信息
     */
    public void initPatiInfo (PatientInfoModel paitentInfo)
    {
        mask ();
        m_drugReturnAndRefundFields.getPatiNameField ().setValue (paitentInfo.getName ());
        m_drugReturnAndRefundFields.getPatiIdField ().setValue (paitentInfo.getPatiId ());
        m_drugReturnAndRefundFields.getSexField ().setValue (paitentInfo.getSex ());
        DateTimeFormat dtFormat = DateTimeFormat.getFormat ("yyyy-MM-dd");
        if (paitentInfo.getBirthDate () != null)
        {
            m_drugReturnAndRefundFields.getBirthDaTetField ().setValue (dtFormat.format (paitentInfo.getBirthDate ()));
        }

        // 查询余额
        m_drugReturnAndRefundFields.getRemainingSumField ().setValue (paitentInfo.getBalance ());
        if (paitentInfo.getChargeType () != null)
        {
            m_drugReturnAndRefundFields.getVisitTypeNameField ().setValue (paitentInfo.getChargeType ());
        }
        if (paitentInfo.getVisitId () != null)
        {
            m_drugReturnAndRefundFields.getVisitIdField ().setValue (paitentInfo.getVisitId ().toString ());
        }

        /*
         * if (paitentInfo.getUpdateTime () != null) {
         * m_drugReturnAndRefundFields.getVisitBeginDateField () .setValue
         * (dtFormat.format (paitentInfo.getMedicareCardPatientInfo ()
         * .getUpdateTime ())); }
         */
        m_drugReturnAndRefundFields.getDeptNameField ().setValue (paitentInfo.getDeptName ());
        m_drugReturnAndRefundFields.getDay ().setValue (paitentInfo.getVisitDay () + "");
        m_drugReturnAndRefundFields.getNumber ().setValue (paitentInfo.getBedCode ());
    }

    /**
     * 通过患者ID查询处方信息
     * 
     * @param patientId
     * @param enterDate
     */
    public void queryByPid (final String patientId, Date enterDate)
    {
        /*
         * S_PRESC_RPC_ASYNC.findPrescNoListByPatientId (patientId, enterDate,
         * new AsyncCallback <List <String>> () {
         * 
         * @Override public void onFailure (Throwable caught) { unmask ();
         * return;
         * 
         * }
         * 
         * @Override public void onSuccess (List <String> result) { String
         * performedBy = ClientUtils.getOrgModel().getOrgCode();
         * 
         * S_DRUG_RETURN_ASYNC.findPrescDetailByPrescList (result, performedBy,
         * new AsyncCallback <PrescAndPatResultModel> () {
         * 
         * @Override public void onSuccess (PrescAndPatResultModel result) { if
         * (result == null || result.getPdsPrescDetailInfoModellist () .isEmpty
         * ()) { ClientUtils.alertMessageBox ("找不到相关处方。",
         * m_drugReturnAndRefundFields.getMedicareCardField ());
         * 
         * unmask (); clear (false); return; }
         * m_drugReturnAndRefundPrescPanel.getStore () .removeAll ();
         * m_drugReturnPrescDetailPanel.getPrescDetailGrid () .getGrid ()
         * .getStore () .removeAll (); m_memoryList =
         * result.getPdsPrescDetailInfoModellist ();
         * m_drugReturnAndRefundPrescPanel.getStore () .add
         * (result.getPdsPrescDetailInfoModellist () .get (0));
         * 
         * unmask ();
         * 
         * }
         * 
         * @Override public void onFailure (Throwable caught) { clear (false);
         * ClientUtils.alertMessageBox (caught.getMessage (),
         * m_drugReturnAndRefundFields.getMedicareCardField ()); unmask (); }
         * }); } });
         */
    }

    /**
     * 查询处方和处方明细信息
     * 
     * @param successComponent
     * @param failComponent
     */
    private void findPrescDetail (final Component successComponent, final Component failComponent)
    {

        final String prescNo = m_drugReturnAndRefundFields.getPrescNoField ().getValue ();
        if (prescNo == null)
        {
            ClientUtils.alertMessageBox ("处方号不能为空！请重新输入。", failComponent);
            return;
        }
        PdsPrescDetailInfoModel model = new PdsPrescDetailInfoModel ();
        model.setPrescNo (prescNo);
        final List <String> prescNoList = new ArrayList <String> ();
        prescNoList.add (prescNo);
        DrugReturnAction.PD_ASYNC.getPrescDetailByPrescAndRcpt (model.getRcptNo (), model.getPrescNo (),
                                                                new AsyncCallback <List <PdsPrescDetailInfoModel>> ()
                                                                {
                                                                    @Override
                                                                    public void onFailure (final Throwable caught)
                                                                    {
                                                                        MessageBox.alert ("警告", caught.getMessage (),
                                                                                          null);
                                                                        clear (false);
                                                                        return;
                                                                    }

                                                                    @Override
                                                                    public void onSuccess (final List <PdsPrescDetailInfoModel> result)
                                                                    {
                                                                        findPrescDetailByPrescNoList (result,
                                                                                                      successComponent,
                                                                                                      failComponent);
                                                                    }
                                                                });

    }

    private void findPrescDetailByPrescNoList (final List <PdsPrescDetailInfoModel> result,
                                               final Component successComponent, final Component failComponent)
    {
        if (result.isEmpty ())
        {
            ClientUtils.alertMessageBox ("处方号不存在，请重新输入。", m_drugReturnAndRefundFields.getPrescNoField ());
            return;
        }
        List <String> prescNoList = new ArrayList <String> ();
        prescNoList.add (m_drugReturnAndRefundFields.getPrescNoField ().getValue ());

        S_DRUG_RETURN_ASYNC.findPrescDetailByPrescList (prescNoList, ClientUtils.getOrgModel ().getOrgCode (),
                                                        new AsyncCallback <PrescAndPatResultModel> ()
                                                        {

                                                            @Override
                                                            public void onFailure (Throwable caught)
                                                            {
                                                                ClientUtils.alertMessageBox (caught.getMessage (),
                                                                                             failComponent);
                                                            }

                                                            @Override
                                                            public void onSuccess (PrescAndPatResultModel result)
                                                            {

                                                                if (ClientUtils.isEmpty (result.getPdsPrescDetailInfoModellist ()))

                                                                {
                                                                    unmask ();
                                                                    final PdsSupplyModel currentCondition = new PdsSupplyModel ();
                                                                    currentCondition.setPrescNo (m_drugReturnAndRefundFields.getPrescNoField ()
                                                                                                                            .getValue ());
                                                                    final SupplyStatusQueryWindow window = new SupplyStatusQueryWindow (
                                                                                                                                        currentCondition,
                                                                                                                                        m_drugReturnAndRefundFields.getPrescNoField ());
                                                                    window.show ();
                                                                    return;
                                                                }
                                                                clear (false);
                                                                m_memoryList = result.getPdsPrescDetailInfoModellist ();
                                                                m_drugReturnAndRefundPrescPanel.getStore ()
                                                                                               .add (result.getPdsPrescDetailInfoModellist ()
                                                                                                           .get (0));
                                                                m_drugReturnAndRefundFields.getPrescSource ()
                                                                                           .setValue (m_drugReturnAndRefundPrescPanel.getStore ()
                                                                                                                                     .getAt (0)
                                                                                                                                     .getPrescSourceName ());
                                                                initPatiInfo (result.getMedicareCardAllInfoModel ());
                                                                if (successComponent != null)
                                                                {
                                                                    successComponent.focus ();
                                                                }
                                                                unmask ();
                                                            }
                                                        });
    }

    /**
     * 通过处方号查询处方和处方明细信息
     * 
     * @param successComponent
     * @param failComponent
     */
    public void findPrescDetailByPresc (final Component successComponent, final Component failComponent)
    {
        mask ();
        clear (false);
        findPrescDetail (successComponent, failComponent);
    }

    private void mask ()
    {
        m_drugReturnMainPanel.mask ("加载中...");
    }

    public void refuseDrugReturn (final Component successComponent)
    {
        if (m_drugReturnAndRefundPrescPanel.getCheckmodel ().getSelectedItems ().isEmpty ())
        {
            ClientUtils.alertMessageBox ("请先选中要拒绝退药的处方再进行此操作", successComponent);
            return;
        }
        m_drugReturnRefuseWindow.clearDate ();
        m_drugReturnRefuseWindow.show ();
    }

    /**
     * 设置门诊退药文本域
     * 
     * @param drugReturnAndRefundFields
     */
    public void setDrugReturnFields (final DrugReturnAndRefundFields drugReturnAndRefundFields)
    {
        m_drugReturnAndRefundFields = drugReturnAndRefundFields;
    }

    /**
     * 设置门诊退药处方明细表格
     * 
     * @param drugReturnPrescDetailPanel
     */
    public void setDrugReturnPrescDetailPanel (final DrugReturnPrescDetailPanel drugReturnPrescDetailPanel)
    {
        m_drugReturnPrescDetailPanel = drugReturnPrescDetailPanel;
    }

    /**
     * 设置门诊退药处方表格
     * 
     * @param drugReturnAndRefundPrescPanel
     */
    public void setDrugReturnPrescPanel (final DrugReturnAndRefundPrescPanel drugReturnAndRefundPrescPanel)
    {
        m_drugReturnAndRefundPrescPanel = drugReturnAndRefundPrescPanel;
    }

    public void setDrugReturnRefuseWindow (final DrugReturnRefuseWindow drugReturnRefuseWindow)
    {
        m_drugReturnRefuseWindow = drugReturnRefuseWindow;
    }

    private void unmask ()
    {
        m_drugReturnMainPanel.unmask ();
    }

    public void setDrugReturnMainPanel (DrugReturnMainPanel drugReturnMainPanel)
    {
        m_drugReturnMainPanel = drugReturnMainPanel;
    }

}
